﻿using Microsoft.Owin.Infrastructure;
using MobileControlGuru.AutoTask;
using MobileControlGuru.Base;
using Newtonsoft.Json;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI;
using System.Windows.Forms;
using static log4net.Appender.RollingFileAppender;
using static MobileControlGuru.AutoTask.TaskJson;
using static Quartz.Logging.OperationName;

namespace MobileControlGuru.Src
{
    public class SchedulerTrigger
    {
        public ITrigger trigger { get; set; }
        public IJobDetail deviceJobdetail { get; set; }
    }

    /// <summary>
    /// 任务管理
    /// </summary>
    public class TaskManager
    {
        private static TaskManager instance = null;
        private static readonly object lockObj = new object();
        private static string JobGroupName = "DeviceCtrlGroup";

        private static string TriggerGroupName = "DeviceCtrlGroup";
        private JobStatusTracker statusTracker;
        public int MaxConcurrentTasks = 20;

        // 假设已经调度的任务存储在scheduledJobKeys中，这里简化为HashSet示例
        public HashSet<string> _scheduledJobKey;
        private TaskManager()
        {

            // 创建一个NameValueCollection来存储配置信息
            NameValueCollection properties = new NameValueCollection
        {
            // 设置调度器的名称
            { "quartz.scheduler.instanceName", "MyScheduler" },
            
            // 设置线程池类型，这里使用默认的线程池
            { "quartz.threadPool.type", "Quartz.Simpl.DefaultThreadPool" },
            
            // 设置线程池的最大并发数
            { "quartz.threadPool.maxConcurrency", "20" } // 例如，这里设置为5
        };

            factory = new StdSchedulerFactory(properties);
            statusTracker = new JobStatusTracker();
            // Step 3: 创建 TaskManagerJob 实例和状态跟踪器

        }
        /// <summary>
        /// 单例模式
        /// </summary>
        public static TaskManager Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (lockObj)
                    {
                        if (instance == null)
                        {
                            instance = new TaskManager();

                        }
                    }
                }
                return instance;
            }
        }

        StdSchedulerFactory factory;
        IScheduler scheduler;


        public async void Start()
        {

            scheduler = await factory.GetScheduler();

            JobStatusListener statusListener = new JobStatusListener(statusTracker);
            scheduler.ListenerManager.AddJobListener(statusListener);

            await scheduler.Start();

        }
        public async Task<TriggerState> GetTriggerStateBy(string TriggerName)
        {

            scheduler = await factory.GetScheduler();
            TriggerKey triggerKey = new TriggerKey(TriggerName, TriggerGroupName);

            return await scheduler.GetTriggerState(triggerKey);


        }

        public async void JobStart(TaskJson.TaskInfo taskInfo)
        {
            try
            {

                Start();



                JobKey jobKey = new JobKey(taskInfo.Name, JobGroupName);
                bool isExistsJob = await scheduler.CheckExists(jobKey);
                if (!isExistsJob)
                {

                    //// 创建并注册作业监听器
                    //IJobListener jobListener = new DeviceCtrlJobListener();
                    //scheduler.ListenerManager.AddJobListener(jobListener);
                    //创建作业
                    IJobDetail deviceJobdetail = JobBuilder.Create<DeviceCtrlJob>().WithIdentity(taskInfo.Name, JobGroupName).Build();


                    string taskinfoJsonString = JsonConvert.SerializeObject(taskInfo);
                    if (!string.IsNullOrEmpty(taskInfo.Corn))
                    {

                        bool isValid = CronExpression.IsValidExpression(taskInfo.Corn);
                        //如果isValid为true，则表示Cron表达式是有效的；如果为false，则表示Cron表达式有误
                        if (!isValid)
                        {
                            MessageBox.Show("Corn 表达式有误");
                            return;
                        }
                        ITrigger trigger = TriggerBuilder.Create()
                                  .WithIdentity(taskInfo.Name, TriggerGroupName)
                                  .StartNow()
                                  .WithCronSchedule(taskInfo.Corn)
                                  .UsingJobData("taskinfo", taskinfoJsonString)
                                  .Build();
                        // 将作业和触发器添加到调度器
                        await scheduler.ScheduleJob(deviceJobdetail, trigger);
                    }
                    else if (taskInfo.StartDeteTime != null && taskInfo.EndDeteTime != null)
                    {
                        DateTimeOffset dateTimeOffsetStart = new DateTimeOffset((DateTime)taskInfo.StartDeteTime);
                        DateTimeOffset dateTimeOffsetEnd = new DateTimeOffset((DateTime)taskInfo.EndDeteTime);
                        ITrigger trigger = TriggerBuilder.Create()
                                                           .WithIdentity(taskInfo.Name, TriggerGroupName)
                                                           .StartAt(dateTimeOffsetStart)
                                                           .EndAt(dateTimeOffsetEnd)    //xxx  s后结束
                                                           .UsingJobData("taskinfo", taskinfoJsonString)
                                                           .Build();
                        // 将作业和触发器添加到调度器
                        await scheduler.ScheduleJob(deviceJobdetail, trigger);
                    }

                    else
                    {

                        ITrigger trigger = TriggerBuilder.Create()
                                                           .WithIdentity(taskInfo.Name, TriggerGroupName)
                                                           .StartNow()     //马上开启
                                                           .WithSimpleSchedule()
                                                           .UsingJobData("taskinfo", taskinfoJsonString)
                                                           .Build();
                        // 将作业和触发器添加到调度器
                        await scheduler.ScheduleJob(deviceJobdetail, trigger);
                    }

                    await scheduler.Start();
                }

            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                throw;
            }


        }

        public async void JobEnd(TaskJson.TaskInfo taskInfo)
        {
            try
            {
                scheduler = await factory.GetScheduler();
                TriggerKey triggerKey = new TriggerKey(taskInfo.Name, TriggerGroupName);

                //// 暂停触发器
                await scheduler.PauseTrigger(triggerKey);
                // 移除触发器及其作业
                await scheduler.UnscheduleJob(triggerKey);
                JobKey jobKey = new JobKey(taskInfo.Name, JobGroupName);
                //// 删除作业
                await scheduler.DeleteJob(jobKey);
                //// 等待所有作业完成后关闭调度器
                //await scheduler.Shutdown(waitForJobsToComplete: true);

                //// 或者不等待当前作业完成，立即关闭调度器
                //await scheduler.Shutdown(waitForJobsToComplete: false);

            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                throw;
            }
        }

        public async void JobDelete(TaskJson.TaskInfo taskInfo)
        {
            try
            {
                scheduler = await factory.GetScheduler();
                TriggerKey triggerKey = new TriggerKey(taskInfo.Name, TriggerGroupName);

                //// 暂停触发器
                await scheduler.PauseTrigger(triggerKey);
                // 移除触发器及其作业
                await scheduler.UnscheduleJob(triggerKey);

                JobKey jobKey = new JobKey(taskInfo.Name);
                // （可选）如果你还想从作业存储中删除作业定义
                await scheduler.DeleteJob(jobKey);


                statusTracker.SetStatus(taskInfo.Name, JobStatus.Completed);

                //// 删除作业
                //await scheduler.DeleteJob(this.deviceJobdetail.Key);
                //// 等待所有作业完成后关闭调度器
                //await scheduler.Shutdown(waitForJobsToComplete: true);

                //// 或者不等待当前作业完成，立即关闭调度器
                //await scheduler.Shutdown(waitForJobsToComplete: false);

            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                throw;
            }
        }


        StdSchedulerFactory taskfactory;
        IScheduler taskscheduler;
        /// <summary>
        /// 每分钟
        /// </summary>
        /// <param name="taskInfos"></param>
        public async void MultiJobStart(List<TaskInfo> taskInfos)
        {
            try
            {
                // Step 1: 定义其他作业和触发器（例如 MyJob）
                // ... （此处省略 MyJob 的定义）

                // Step 2: 配置 Quartz.NET（通常在应用程序启动时完成）
                taskfactory = new StdSchedulerFactory();
                taskscheduler = await taskfactory.GetScheduler();
                //

                HashSet<string> scheduledJobKeys = new HashSet<string> { /* 已调度任务的jobKey */ };

                _scheduledJobKey = scheduledJobKeys;
                JobKey jobKey = new JobKey("taskManagerJob", "taskManagergroup");
                bool isExistsJob = await taskscheduler.CheckExists(jobKey);
                if (!isExistsJob)
                {
                    // 创建 TaskManagerJob 的 JobDetail 和 Trigger
                    IJobDetail taskManagerJobDetail = JobBuilder.Create<TaskManagerJob>()
                    .WithIdentity("taskManagerJob", "taskManagergroup")
                    .Build();

                    ITrigger taskManagerTrigger = TriggerBuilder.Create()
                        .WithIdentity("taskManagerTrigger", "taskManagergroup")
                        .StartNow()
                        .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever()) // 每xx秒执行一次
                        .Build();

                    // Step 4: 调度 TaskManagerJob
                    await taskscheduler.ScheduleJob(taskManagerJobDetail, taskManagerTrigger);
                    // Step 5: 启动调度器
                    await taskscheduler.Start();

                }




                // 注意：在实际应用中，你可能还需要配置日志记录、异常处理等。
            }
            catch (Exception ex)
            {
                Tools.LogHelper.Error(ex);

            }


        }

        public async void MultiJobEnd(List<TaskInfo> taskInfos)
        {

            if (taskscheduler == null) return;
            TriggerKey triggerKey = new TriggerKey("taskManagerJob", "taskManagergroup");
            JobKey jobKey = new JobKey("taskManagerJob", "taskManagergroup");
            if (!taskscheduler.IsShutdown)
            {
                bool isExistsJob = await taskscheduler.CheckExists(jobKey);
                if (!isExistsJob)
                {
                    //// 暂停触发器
                    await taskscheduler.PauseTrigger(triggerKey);
                    // 移除触发器及其作业
                    await taskscheduler.UnscheduleJob(triggerKey);


                    // （可选）如果你还想从作业存储中删除作业定义
                    await taskscheduler.DeleteJob(jobKey);
                    foreach (TaskJson.TaskInfo item in taskInfos)
                    {
                        JobEnd(item);
                    }

                }
                await taskscheduler.Shutdown();
            }
          
         
          
        }

        public async void MultiJobDelete(List<TaskInfo> taskInfos)
        {
            if (taskscheduler == null) return;
            TriggerKey triggerKey = new TriggerKey("taskManagerJob", "taskManagergroup");

            //// 暂停触发器
            await taskscheduler.PauseTrigger(triggerKey);
            // 移除触发器及其作业
            await taskscheduler.UnscheduleJob(triggerKey);

            JobKey jobKey = new JobKey("taskManagerJob");
            // （可选）如果你还想从作业存储中删除作业定义
            await taskscheduler.DeleteJob(jobKey);
            foreach (TaskJson.TaskInfo item in taskInfos)
            {
                JobDelete(item);
            }
        }

        public void LoopNext()
        {
            Start();
            // 查询当前正在运行的任务数量
            int scheduledCount = statusTracker.CountScheduledJobs();

            // 检查是否还有未调度的任务，并且当前运行的任务数少于最大并发数
            while (scheduledCount < MaxConcurrentTasks && TryGetNextJobToSchedule(out IJobDetail nextJobDetail, out ITrigger nextTrigger))
            {
                // 标记任务为Scheduled状态（如果需要的话，这步可以省略，因为一旦ScheduleJob被调用，可以认为任务就是Scheduled状态了）
                statusTracker.SetStatus(nextJobDetail.Key.ToString(), JobStatus.Scheduled);

                // 调度下一个任务
                scheduler.ScheduleJob(nextJobDetail, nextTrigger);

                // 更新运行中的任务计数（这里假设任务会立即开始执行，实际情况可能有所不同）
                scheduledCount++;

                // 可选：记录日志或进行其他通知操作
                //
                string msg = $"开启任务线程监听：{nextJobDetail.Key}";

                ShowLogMsg(msg);
                Console.WriteLine($"{msg}");
            }

            string scheduledmsg = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ")}运行线程数：{scheduledCount}";

            //// 确保在UI线程上执行
            if (Application.OpenForms.Count > 0)
            {
                Application.OpenForms[0].Invoke((MethodInvoker)delegate
                {
                    TaskList taskList = TaskList.GetInstance();
                    // 触发UI更新事件
                    taskList.OnUIUpdate(scheduledmsg);

                });
            }
        }
        private void ShowLogMsg(string msg)
        {
            //// 确保在UI线程上执行
            //if (Application.OpenForms.Count > 0)
            //{
            //    Application.OpenForms[0].Invoke((MethodInvoker)delegate
            //    {
            //        LogForm logForm = LogForm.GetInstance();
            //        if (!logForm.Visible)
            //        {
            //            logForm.Show();
            //        }
            //        logForm.AppendLog($"{DateTime.Now}:{msg}");

            //    });
            //}
            //else
            //{
            //    // 如果没有打开的窗体，可以考虑其他处理方式
            //    Console.WriteLine("No open forms to attach the log window to.");
            //}
        }

        private bool TryGetNextJobToSchedule(out IJobDetail jobDetail, out ITrigger trigger)
        {
            // 这里应该实现逻辑来从任务队列、数据库或其他存储中获取下一个未调度的任务
            // 并将其JobDetail和Trigger赋值给out参数。如果没有更多任务，返回false。

            jobDetail = null;
            trigger = null;



            try
            {

                //获取所有任务列表
                List<TaskInfo> tasks = TaskJson.Instance.tasks;
                // 使用 LINQ 对列表进行排序
                var sortedTaskInfos = tasks
                    .Where(ti => ti.StartDeteTime.HasValue) // 可选：仅包含有 StartDateTime 的项
                    .OrderBy(ti => ti.StartDeteTime.Value) // 按 StartDateTime 升序排序
                    .ToList(); // 将结果转换回 List<TaskInfo>
                // 查找下一个未调度的任务
                TaskInfo nextTaskToken = sortedTaskInfos.FirstOrDefault(t => !_scheduledJobKey.Contains(t.Name));
                if (nextTaskToken != null && nextTaskToken.StartDeteTime != null)
                {

                    if (nextTaskToken.StartDeteTime > DateTime.Now)
                    {
                        SchedulerTrigger schedulerTrigger = CreateJob(nextTaskToken);
                        jobDetail = schedulerTrigger.deviceJobdetail;
                        trigger = schedulerTrigger.trigger;
                        return true;
                    }
                    else
                    {
                        // 检查dateTime1和dateTime2之间的间隔是否小于或等于一秒
                        TimeSpan difference = DateTime.Now - (DateTime)nextTaskToken.StartDeteTime;
                        if (difference <= TimeSpan.FromSeconds(5))
                        {
                            Console.WriteLine("dateTime1 和 dateTime2 之间的间隔小于或等于5秒。");
                            SchedulerTrigger schedulerTrigger = CreateJob(nextTaskToken);
                            jobDetail = schedulerTrigger.deviceJobdetail;
                            trigger = schedulerTrigger.trigger;
                            return true;
                        }
                        else
                        {
                            Console.WriteLine("dateTime1 和 dateTime2 之间的间隔大于5秒。");
                            string msg = $"无法启动任务线程监听：{nextTaskToken.Name}。请检查时间！任务时间已超！";
                            ShowLogMsg(msg);
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                // 处理文件读取错误、JSON解析错误等
                Console.WriteLine($"Error reading or parsing tasks JSON: {ex.Message}");
            }

            return false;
        }

        /// <summary>
        /// 创建任务及触发器
        /// </summary>
        /// <param name="taskInfo"></param>
        /// <returns></returns>
        public SchedulerTrigger CreateJob(TaskJson.TaskInfo taskInfo)
        {

            SchedulerTrigger schedulerTrigger = new SchedulerTrigger();
            try
            {
                //创建作业
                IJobDetail deviceJobdetail = JobBuilder.Create<DeviceCtrlJob>().WithIdentity(taskInfo.Name, JobGroupName).Build();


                schedulerTrigger.deviceJobdetail = deviceJobdetail;

                string taskinfoJsonString = JsonConvert.SerializeObject(taskInfo);
                if (!string.IsNullOrEmpty(taskInfo.Corn))
                {
                    CronExpression.ValidateExpression(taskInfo.Corn);

                    ITrigger trigger = TriggerBuilder.Create()
                                                      .WithIdentity(taskInfo.Name, TriggerGroupName)
                                                      .StartNow()
                                                      .WithCronSchedule(taskInfo.Corn)
                                                      .UsingJobData("taskinfo", taskinfoJsonString)
                                                      .Build();
                    schedulerTrigger.trigger = trigger;
                }
                else if (taskInfo.StartDeteTime != null && taskInfo.EndDeteTime != null)
                {
                    DateTimeOffset dateTimeOffsetStart = new DateTimeOffset((DateTime)taskInfo.StartDeteTime);
                    DateTimeOffset dateTimeOffsetEnd = new DateTimeOffset((DateTime)taskInfo.EndDeteTime);
                    ITrigger trigger = TriggerBuilder.Create()
                                                       .WithIdentity(taskInfo.Name, TriggerGroupName)
                                                       .StartAt(dateTimeOffsetStart)
                                                       .EndAt(dateTimeOffsetEnd)    //xxx  s后结束
                                                       .UsingJobData("taskinfo", taskinfoJsonString)
                                                       .Build();
                    schedulerTrigger.trigger = trigger;
                }

                else
                {

                    ITrigger trigger = TriggerBuilder.Create()
                                                       .WithIdentity(taskInfo.Name, TriggerGroupName)
                                                       .StartNow()     //马上开启
                                                       .WithSimpleSchedule()
                                                       .UsingJobData("taskinfo", taskinfoJsonString)
                                                       .Build();
                    //// 将作业和触发器添加到调度器
                    //await scheduler.ScheduleJob(deviceJobdetail, trigger);
                    schedulerTrigger.trigger = trigger;
                }

                _scheduledJobKey.Add(taskInfo.Name);

            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                throw;
            }
            return schedulerTrigger;

        }
    }
}
